import { ref, onMounted, onUnmounted } from 'vue'

/**
 * 性能监控组合式函数
 * @returns {Object} 性能监控数据和方法
 */
export function usePerformance() {
  const metrics = ref({
    fps: 0,
    memory: {
      used: 0,
      total: 0,
      percentage: 0
    },
    timing: {
      domContentLoaded: 0,
      loadComplete: 0,
      firstPaint: 0,
      firstContentfulPaint: 0
    },
    resources: {
      count: 0,
      totalSize: 0,
      loadTime: 0
    }
  })

  const isMonitoring = ref(false)
  let fpsCounter = null
  let memoryMonitor = null
  let performanceObserver = null

  // FPS监控
  const startFPSMonitoring = () => {
    let frames = 0
    let lastTime = performance.now()

    const countFPS = () => {
      frames++
      const currentTime = performance.now()
      
      if (currentTime >= lastTime + 1000) {
        metrics.value.fps = Math.round((frames * 1000) / (currentTime - lastTime))
        frames = 0
        lastTime = currentTime
      }
      
      if (isMonitoring.value) {
        fpsCounter = requestAnimationFrame(countFPS)
      }
    }

    fpsCounter = requestAnimationFrame(countFPS)
  }

  // 内存监控
  const startMemoryMonitoring = () => {
    if (!performance.memory) return

    const updateMemory = () => {
      const memory = performance.memory
      metrics.value.memory = {
        used: Math.round(memory.usedJSHeapSize / 1024 / 1024),
        total: Math.round(memory.totalJSHeapSize / 1024 / 1024),
        percentage: Math.round((memory.usedJSHeapSize / memory.totalJSHeapSize) * 100)
      }
    }

    updateMemory()
    memoryMonitor = setInterval(updateMemory, 1000)
  }

  // 页面加载性能监控
  const measurePagePerformance = () => {
    if (!performance.timing) return

    const timing = performance.timing
    const navigation = performance.getEntriesByType('navigation')[0]

    metrics.value.timing = {
      domContentLoaded: timing.domContentLoadedEventEnd - timing.navigationStart,
      loadComplete: timing.loadEventEnd - timing.navigationStart,
      firstPaint: 0,
      firstContentfulPaint: 0
    }

    // 获取绘制性能
    if (performance.getEntriesByType) {
      const paintEntries = performance.getEntriesByType('paint')
      paintEntries.forEach(entry => {
        if (entry.name === 'first-paint') {
          metrics.value.timing.firstPaint = Math.round(entry.startTime)
        } else if (entry.name === 'first-contentful-paint') {
          metrics.value.timing.firstContentfulPaint = Math.round(entry.startTime)
        }
      })
    }

    // 资源加载性能
    const resources = performance.getEntriesByType('resource')
    let totalSize = 0
    let totalLoadTime = 0

    resources.forEach(resource => {
      if (resource.transferSize) {
        totalSize += resource.transferSize
      }
      totalLoadTime += resource.responseEnd - resource.startTime
    })

    metrics.value.resources = {
      count: resources.length,
      totalSize: Math.round(totalSize / 1024), // KB
      loadTime: Math.round(totalLoadTime)
    }
  }

  // 性能观察器
  const startPerformanceObserver = () => {
    if (!window.PerformanceObserver) return

    try {
      performanceObserver = new PerformanceObserver((list) => {
        const entries = list.getEntries()
        entries.forEach(entry => {
          if (entry.entryType === 'measure') {
            console.log(`Performance measure: ${entry.name} - ${entry.duration}ms`)
          } else if (entry.entryType === 'mark') {
            console.log(`Performance mark: ${entry.name} at ${entry.startTime}ms`)
          }
        })
      })

      performanceObserver.observe({ entryTypes: ['measure', 'mark'] })
    } catch (error) {
      console.warn('Performance Observer not supported:', error)
    }
  }

  // 开始监控
  const startMonitoring = () => {
    if (isMonitoring.value) return

    isMonitoring.value = true
    startFPSMonitoring()
    startMemoryMonitoring()
    startPerformanceObserver()
    measurePagePerformance()
  }

  // 停止监控
  const stopMonitoring = () => {
    isMonitoring.value = false

    if (fpsCounter) {
      cancelAnimationFrame(fpsCounter)
      fpsCounter = null
    }

    if (memoryMonitor) {
      clearInterval(memoryMonitor)
      memoryMonitor = null
    }

    if (performanceObserver) {
      performanceObserver.disconnect()
      performanceObserver = null
    }
  }

  // 性能标记
  const mark = (name) => {
    if (performance.mark) {
      performance.mark(name)
    }
  }

  // 性能测量
  const measure = (name, startMark, endMark) => {
    if (performance.measure) {
      try {
        performance.measure(name, startMark, endMark)
      } catch (error) {
        console.warn('Performance measure failed:', error)
      }
    }
  }

  // 获取性能报告
  const getPerformanceReport = () => {
    return {
      timestamp: new Date().toISOString(),
      metrics: { ...metrics.value },
      userAgent: navigator.userAgent,
      url: window.location.href,
      viewport: {
        width: window.innerWidth,
        height: window.innerHeight
      }
    }
  }

  // 性能评分
  const getPerformanceScore = () => {
    let score = 100

    // FPS评分 (权重: 30%)
    if (metrics.value.fps < 30) score -= 30
    else if (metrics.value.fps < 45) score -= 15
    else if (metrics.value.fps < 55) score -= 5

    // 内存使用评分 (权重: 25%)
    if (metrics.value.memory.percentage > 80) score -= 25
    else if (metrics.value.memory.percentage > 60) score -= 15
    else if (metrics.value.memory.percentage > 40) score -= 5

    // 页面加载评分 (权重: 25%)
    if (metrics.value.timing.loadComplete > 5000) score -= 25
    else if (metrics.value.timing.loadComplete > 3000) score -= 15
    else if (metrics.value.timing.loadComplete > 2000) score -= 5

    // 首次内容绘制评分 (权重: 20%)
    if (metrics.value.timing.firstContentfulPaint > 3000) score -= 20
    else if (metrics.value.timing.firstContentfulPaint > 2000) score -= 10
    else if (metrics.value.timing.firstContentfulPaint > 1500) score -= 5

    return Math.max(0, score)
  }

  // 性能建议
  const getPerformanceSuggestions = () => {
    const suggestions = []

    if (metrics.value.fps < 30) {
      suggestions.push({
        type: 'warning',
        message: 'FPS过低，建议减少动画效果或优化渲染性能'
      })
    }

    if (metrics.value.memory.percentage > 70) {
      suggestions.push({
        type: 'warning',
        message: '内存使用率过高，建议清理不必要的数据或组件'
      })
    }

    if (metrics.value.timing.loadComplete > 3000) {
      suggestions.push({
        type: 'info',
        message: '页面加载时间较长，建议优化资源加载'
      })
    }

    if (metrics.value.resources.totalSize > 5000) {
      suggestions.push({
        type: 'info',
        message: '资源文件较大，建议启用压缩或使用CDN'
      })
    }

    return suggestions
  }

  // 生命周期
  onMounted(() => {
    // 页面加载完成后开始监控
    if (document.readyState === 'complete') {
      startMonitoring()
    } else {
      window.addEventListener('load', startMonitoring)
    }
  })

  onUnmounted(() => {
    stopMonitoring()
    window.removeEventListener('load', startMonitoring)
  })

  return {
    metrics,
    isMonitoring,
    startMonitoring,
    stopMonitoring,
    mark,
    measure,
    getPerformanceReport,
    getPerformanceScore,
    getPerformanceSuggestions
  }
}

/**
 * 函数执行时间测量
 * @param {Function} fn 要测量的函数
 * @param {string} name 测量名称
 * @returns {Function} 包装后的函数
 */
export function measureFunction(fn, name) {
  return async function(...args) {
    const startMark = `${name}-start`
    const endMark = `${name}-end`
    const measureName = `${name}-duration`

    performance.mark(startMark)
    
    try {
      const result = await fn.apply(this, args)
      performance.mark(endMark)
      performance.measure(measureName, startMark, endMark)
      
      const measure = performance.getEntriesByName(measureName)[0]
      console.log(`${name} 执行时间: ${measure.duration.toFixed(2)}ms`)
      
      return result
    } catch (error) {
      performance.mark(endMark)
      performance.measure(measureName, startMark, endMark)
      throw error
    }
  }
}

/**
 * 组件渲染性能监控
 * @param {string} componentName 组件名称
 * @returns {Object} 监控方法
 */
export function useComponentPerformance(componentName) {
  const renderTimes = ref([])
  const averageRenderTime = computed(() => {
    if (renderTimes.value.length === 0) return 0
    const sum = renderTimes.value.reduce((a, b) => a + b, 0)
    return sum / renderTimes.value.length
  })

  const startRender = () => {
    performance.mark(`${componentName}-render-start`)
  }

  const endRender = () => {
    performance.mark(`${componentName}-render-end`)
    performance.measure(
      `${componentName}-render`,
      `${componentName}-render-start`,
      `${componentName}-render-end`
    )

    const measure = performance.getEntriesByName(`${componentName}-render`)[0]
    if (measure) {
      renderTimes.value.push(measure.duration)
      
      // 只保留最近20次的渲染时间
      if (renderTimes.value.length > 20) {
        renderTimes.value.shift()
      }
    }
  }

  return {
    renderTimes,
    averageRenderTime,
    startRender,
    endRender
  }
}



